#!/usr/bin/python
# -*- coding: iso-8859-1 -*-

try:
    import wx
except ImportError:
    raise ImportError,"The wxPython module is required to run this program"

try:
    import os
except ImportError:
    raise ImportError,"The OS module is required to run this program"

try:
    import socket, struct, fcntl
except ImportError:
    raise ImportError,"Socket module is required to run this program"

try:
    from threading import Thread
except ImportError:
    raise ImportError,"Threading module is required to run this program"

try:
    import time
except ImportError:
    raise ImportError,"time module is required to run this program"

from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
import numpy as np




class TCPDPanel(wx.Panel):
    #----------------------------------------------------------------------
    def __init__(self, parent, page):
        """"""
        wx.Panel.__init__(self, parent=parent)
        self.page = page	
	font = wx.SystemSettings_GetFont(wx.SYS_SYSTEM_FONT)
        font.SetPointSize(9)        
	
	self.iface="wlan0"
	self.read=255
	vsizer = wx.BoxSizer(wx.VERTICAL)	
	vinsizer = wx.BoxSizer(wx.VERTICAL)	
	voutsizer= wx.BoxSizer(wx.VERTICAL) 
	vrightsizer = wx.BoxSizer(wx.VERTICAL)		
	hsizer1= wx.BoxSizer(wx.HORIZONTAL)
 	hsizer2= wx.BoxSizer(wx.HORIZONTAL)
	hsizer3= wx.BoxSizer(wx.HORIZONTAL)
	hsizer4= wx.BoxSizer(wx.HORIZONTAL)
	hsizer5= wx.BoxSizer(wx.HORIZONTAL)

	sb1 = wx.StaticBox(self, label="Monitor de capturas")             
	
	self.tc0 = wx.TextCtrl(self, style=wx.TE_READONLY | wx.TE_MULTILINE | wx.HSCROLL)
	self.tc0.SetFont(font)
	wx.EVT_TEXT(self.tc0, self.tc0.GetId(), self.OnText) 
	

	boxsizer1 = wx.StaticBoxSizer(sb1, wx.HORIZONTAL)
        boxsizer1.Add(self.tc0, proportion=1, flag=wx.EXPAND) 
	st1 = wx.StaticText(self, label='Directorio:')
        st1.SetFont(font)

	self.tc1 = wx.TextCtrl(self)
	self.tc1.SetFont(font)

 	btn1 = wx.Button(self, label='Navegador', size=(100, 26))
        btn1.SetFont(font)
 	btn1.Bind(wx.EVT_BUTTON, self.onDir)	
	hsizer1.Add(st1, flag=wx.RIGHT, border=8)
	hsizer1.Add(self.tc1, proportion=1)
	hsizer1.Add(btn1)
	  	
	sb2 = wx.StaticBox(self, label="Opciones de Captura")
	sb2.SetFont(font)	
	boxsizer2 = wx.StaticBoxSizer(sb2, wx.VERTICAL)			
	rb1 = wx.RadioButton ( self, -1, 'wlan', style = wx.RB_GROUP )
	rb1.SetFont(font)	
	self.rb2 = wx.RadioButton ( self, -1, 'eth' )
	self.rb2.SetFont(font)
	self.rb3 = wx.RadioButton ( self, -1, 'lo' ) 	
	self.rb3.SetFont(font)
	rb1.Bind(wx.EVT_RADIOBUTTON, self.confirm)	
	self.rb2.Bind(wx.EVT_RADIOBUTTON, self.confirm)  	
	self.rb3.Bind(wx.EVT_RADIOBUTTON, self.confirm)
        
        self.sc = wx.SpinCtrl(self)
        self.sc.SetRange(0, 100)
        self.sc.SetValue(0)
        self.sc.Bind(wx.EVT_SPINCTRL, self.confirm)		
	
	vinsizer.Add(rb1, flag=wx.RIGHT, border=20)
	vinsizer.Add(self.rb2, flag=wx.RIGHT, border=20)
	vinsizer.Add(self.rb3, flag=wx.RIGHT, border=20)
	vinsizer.Add(self.sc, flag=wx.RIGHT, border=0)

	
	sb4 = wx.StaticBox(self, label="Interfaz")
	sb4.SetFont(font)	
	boxsizer4 = wx.StaticBoxSizer(sb4, wx.HORIZONTAL)
	boxsizer4.Add(vinsizer, flag=wx.RIGHT)

	sb3 = wx.StaticBox(self, label="Filtro de banderas de TCP")
	sb3.SetFont(font)	
	boxsizer3 = wx.StaticBoxSizer(sb3, wx.HORIZONTAL)
	flags=['FIN','SYN','RST','PSH','ACK','URG','ECN','CWR']	
	self.clb1=wx.CheckListBox(self, -1,(1,1), (180,100), flags, style=wx.LB_HSCROLL, name="listbox")
	self.clb1.SetFont(font)	
	
	boxsizer3.Add(self.clb1, flag=wx.RIGHT) 	
	hsizer2.Add(boxsizer4, flag=wx.RIGHT, border=30)
	hsizer2.Add(boxsizer3, flag=wx.RIGHT, border=20)
	
	self.tc3 = wx.TextCtrl(self)
	self.tc3.SetFont(font)
	btn4 = wx.Button(self, label='Obtener', size=(100, 26))
        btn4.SetFont(font)
	btn4.Bind(wx.EVT_BUTTON, self.get_ip)		
	hsizer4.Add(self.tc3, proportion=1)
 	hsizer4.Add(btn4)
	st1 = wx.StaticText(self, label='Ip fuente(formato=>x.x.x.x):')
        st1.SetFont(font)	
	voutsizer.Add(hsizer2, flag=wx.RIGHT, border=20)
	voutsizer.Add(st1, flag=wx.RIGHT | wx.EXPAND, border=0)	
	voutsizer.Add(hsizer4, flag=wx.RIGHT | wx.EXPAND, border=0)
	boxsizer2.Add(voutsizer, flag=wx.RIGHT)

	hsizer5.Add(boxsizer2, flag=wx.RIGHT, border=20)
	self.btn5 = wx.Button(self, label='Ejecutar', size=(136, 50))
	self.btn5.Bind(wx.EVT_BUTTON, self.Onexec)        
	#btn5.SetFont(font)
	self.btn6 = wx.Button(self, label='Detener', size=(136, 50))
        #btn6.SetFont(font)
	self.btn6.Disable()
	self.btn6.Bind(wx.EVT_BUTTON, self.Onstop)
	
	vrightsizer.Add((-1,66))	
	vrightsizer.Add(self.btn5,flag=wx.BOTTOM | wx.RIGHT | wx.ALIGN_RIGHT, border=15)
	vrightsizer.Add(self.btn6, flag=wx.BOTTOM | wx.RIGHT, border=0)
	hsizer5.Add(vrightsizer, flag=wx.BOTTOM | wx.ALIGN_RIGHT, border=10)	
	
	vsizer.Add(boxsizer1,proportion=1, flag=wx.EXPAND|wx.LEFT|wx.RIGHT, border=10)	
	vsizer.Add(hsizer1, flag=wx.EXPAND|wx.LEFT|wx.RIGHT|wx.TOP, border=10)
 	vsizer.Add(wx.StaticLine(self), 0, wx.ALL|wx.EXPAND, 5)	
	vsizer.Add(hsizer5, flag=wx.LEFT|wx.RIGHT|wx.TOP, border=10)		
	self.SetSizer(vsizer)
        
	self.Show(True)

    def OnText(self, event): 
        self.tc0.ScrollPages(1) 

    def onDir(self, event):
	"""	        
	Show the DirDialog and print the user's choice to stdout
	"""
	dlg = wx.DirDialog(self, "Choose a directory:",
                           style=wx.DD_DEFAULT_STYLE
                           #| wx.DD_DIR_MUST_EXIST
	                   #| wx.DD_CHANGE_DIR
			   )
	if dlg.ShowModal() == wx.ID_OK:
		self.tc1.SetValue(dlg.GetPath()+"/clients.txt")
	dlg.Destroy()
    
    def onInc(self, event):
	self.tc2.SetValue(str(int(self.tc2.GetValue())+1))
	self.confirm(wx.EVT_BUTTON)

    def onDec(self, event):
	if (int(self.tc2.GetValue())>0):
		self.tc2.SetValue(str(int(self.tc2.GetValue())-1))
		self.confirm(wx.EVT_BUTTON)

    def confirm ( self, event ):
	if(self.rb3.GetValue() == True):
         	self.sc.Disable()
		self.iface="lo"
	else:
		self.sc.Enable()
		if(self.rb2.GetValue() == True):
			self.iface="eth"+str(self.sc.GetValue())
		else:
			self.iface="wlan"+str(self.sc.GetValue())
			


    def get_ip(self, event):
	sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
	sockfd = sock.fileno()
	SIOCGIFADDR = 0x8915

	ifreq = struct.pack('16sH14s', self.iface, socket.AF_INET, '\x00'*14)
	try:
		res = fcntl.ioctl(sockfd, SIOCGIFADDR, ifreq)
	except:
		self.tc3.SetValue("No encontrada!")
	ip = struct.unpack('16sH2x4s8x', res)[2]
	self.tc3.SetValue(socket.inet_ntoa(ip))

    def Onread(self):
	f=open(self.tc1.GetValue(),'r')	
	while self.read:			
    		where = f.tell()
    		line = f.readline()
    		if not line:
        		time.sleep(0.1)
        		f.seek(where)
    		else:
			wx.CallAfter(self.Update, line)
			time.sleep(0.01)			
        	   
	
    def Onexec(self, event):
	
	self.read=1	
	self.btn5.Disable()
	self.btn6.Enable()
	fchecks=self.clb1.GetChecked()
	value=0	
	for flag in fchecks:
		value+=(2**flag)
	os.system("touch "+self.tc1.GetValue())		
	DUMP= "sudo tcpdump -i "+self.iface+" -n -l 'tcp[tcpflags]&"+str(value)+"!=0' and src host "+self.tc3.GetValue()+" >> "+self.tc1.GetValue()
	self.tc0.AppendText(DUMP+"\n")
	os.system(DUMP+" &")
	Thread(target=self.Onread).start()
	

    def Onstop(self, event):

	self.read=0	
	self.btn5.Enable()
	self.btn6.Disable()
	pid=[]	
	pid.append(os.popen('pidof tcpdump').readline())					
	os.system("sudo kill "+pid[0])
	os.system("rm "+self.tc1.GetValue())
	self.tc0.AppendText("FIN>--------------------------------------------------------------------------------------------<FIN\n")
         

    def Update(self, msg):

	self.tc0.AppendText(msg) 
	

class MPanel(wx.Panel):
    #----------------------------------------------------------------------
    def __init__(self, parent, page):
        """"""
        wx.Panel.__init__(self, parent=parent)
        self.page = page
	font = wx.SystemSettings_GetFont(wx.SYS_SYSTEM_FONT)
        font.SetPointSize(9)

	vsizer = wx.BoxSizer(wx.VERTICAL)
	hsizer = wx.BoxSizer(wx.HORIZONTAL)
	
	sb1 = wx.StaticBox(self, label='Estado')
	sb1.SetFont(font)
	boxsizer1 = wx.StaticBoxSizer(sb1, wx.HORIZONTAL)	
	st1 = wx.StaticText(self, label='Desconectado')	        
	st1.SetForegroundColour((255,0,0))
	
	st2 = wx.StaticText(self, label='@0.0.0.0')
        st3 = wx.StaticText(self, label='Q_ID::  ? ', style=wx.ALIGN_RIGHT)
        
        item = wx.ListItem()
        item.SetText("Prueba")   
	self.lc = wx.ListCtrl(self, -1, style=wx.LC_REPORT | wx.LC_VIRTUAL)
        self.lc.InsertColumn(0, '#')
        self.lc.InsertColumn(1, 'ID')
        self.lc.InsertColumn(2, 'Evento')
        self.lc.InsertColumn(3, 'Fecha')
        num_items = self.lc.GetItemCount()  
        self.lc.InsertItem(item) 
        self.lc.SetStringItem(num_items, 0, str(num_items))
        self.lc.SetStringItem(num_items, 1, str(118))
	self.lc.SetStringItem(num_items, 2, item.GetText())
        self.lc.SetStringItem(num_items, 3, "Sat 20 Apr 2013 01:29:49 AM AST")




	hsizer.Add(st3, flag=wx.ALIGN_RIGHT, border=8)     
	boxsizer1.Add(st1, flag=wx.ALIGN_LEFT | wx.RIGHT, border=0)
	boxsizer1.Add(st2, flag=wx.ALIGN_LEFT | wx.RIGHT , border=320)  
        boxsizer1.Add(st3, flag=wx.ALIGN_RIGHT, border=8)  

	vsizer.Add(boxsizer1, flag=wx.RIGHT | wx.TOP | wx.EXPAND, border=10)
        vsizer.Add(self.lc, flag=wx.RIGHT | wx.TOP | wx.EXPAND, border=10)
	self.SetSizer(vsizer)
	self.Show(True)

	 	 
	           
	
	
	
	


class simpleapp_wx(wx.Frame):
    def __init__(self):
        wx.Frame.__init__(self,None,wx.ID_ANY,
                          "Cliente Quimera",size=(600,400))
        self.initialize()


    def initialize(self):
       
 	panel = wx.Panel(self)
        notebook = wx.Notebook(panel)
        tcpdtab = TCPDPanel(notebook, 1)
	monitortab = MPanel(notebook, 2)         
	notebook.AddPage(tcpdtab, "TCP-DUMP")
	notebook.AddPage(monitortab, "Monitor-Q")
        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(notebook, 1, wx.ALL|wx.EXPAND, 5)
        panel.SetSizer(sizer)
        self.Layout()
        self.Show()


if __name__ == "__main__":
    app = wx.App()
    frame = simpleapp_wx()
    app.MainLoop()
